package com.dc.datacollect.helpers;

import com.dc.datacollect.components.cache.Cache;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;


@Component
@Slf4j
public class VerificationCodeProvide {
    private short CODE_LENGTH = 4;
    private String SOURCE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    @Autowired
    private Cache cache;

    private Map<String,CodeWrap> codeCache = new HashMap<>(8);


    @Data
    private static class CodeWrap {
        /**
         * 验证码
         */
        private String code;
        /**
         * 过期时间
         */
        private Long expirationTime;

        public CodeWrap(String code, Long expirationTime) {
            this.code = code;
            this.expirationTime = expirationTime;
        }
    }
    /**
     * 生成验证码
     *
     * @param id                id
     * @param effectiveDuration 有效时间
     * @return {@link String}
     */
    public String genCode(String id,Long effectiveDuration) {
        StringBuilder captcha = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < CODE_LENGTH; i++) {
            int index = random.nextInt(SOURCE_CHARS.length());
            captcha.append(SOURCE_CHARS.charAt(index));
        }
        // 生成的验证码
        String  verificationCode = captcha.toString().toUpperCase();
        // 将生成的验证码存在差
        CodeWrap codeWrap = new CodeWrap(verificationCode,System.currentTimeMillis()+effectiveDuration);
        codeCache.put(id,codeWrap);
        return verificationCode;
    }
    public boolean verifyCode(String id,String code) throws Exception {
        CodeWrap codeWrap = codeCache.get(id);
        if (codeWrap == null) {
            throw new Exception("验证码不存在！");
        }
        if (codeWrap.getCode().equals(code)) {
            // 验证成功，清理验证码
            codeCache.remove(id);
            return true;
        }
        throw new Exception("验证码错误！");
    }
    @Scheduled(cron = "00 */1 * ? * *")
    private void clearExpireCode() {
        log.info("Cleaning up expired verification codes ...");
        int clearCount = 0;
        Set<String> ids = codeCache.keySet();
        for (String id : ids) {
            CodeWrap codeWrap = codeCache.get(id);
            if (codeWrap.expirationTime < System.currentTimeMillis()) {
                // 当前code 已经过期，移除
                codeCache.remove(id);
                clearCount++;
            }
        }
        log.info("Cleaned up {} expired verification codes, and there are still {} verification codes in the cache",clearCount,codeCache.size());
    }

}
